﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace MKDiractorySearch
{
    /// <summary>
    /// MKDirectory class
    /// </summary>
    public class MKDirectory
    {
        /// <summary>
        /// Gets the child directories.
        /// </summary>
        public IEnumerable<MKDirectory> ChildDirectories { get; private set; }

        /// <summary>
        /// Gets the child files.
        /// </summary>
        public IEnumerable<MKFile> ChildFiles { get; private set; }

        /// <summary>
        /// Gets or sets the name of the directory.
        /// </summary>
        /// <value>
        /// The name of the directory.
        /// </value>
        public string Name { get; set; }

        /// <summary>
        /// Gets or sets the directory path.
        /// </summary>
        /// <value>
        /// The directory path.
        /// </value>
        public string ParentPath { get; set; }

        /// <summary>
        /// Gets or sets the path.
        /// </summary>
        /// <value>
        /// The path.
        /// </value>
        public string Path { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether this instance is empty directory.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance is empty directory; otherwise, <c>false</c>.
        /// </value>
        public bool IsEmptyDirectory { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether this instance is directory.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance is directory; otherwise, <c>false</c>.
        /// </value>
        public bool IsDirectory { get; set; }

        /// <summary>
        /// Gets or sets the file count.
        /// </summary>
        /// <value>
        /// The file count.
        /// </value>
        public int FileCount { get; set; }

        /// <summary>
        /// Gets or sets the size.
        /// </summary>
        /// <value>
        /// The size.
        /// </value>
        public long Size { get; set; }

        /// <summary>
        /// Prevents a default instance of the <see cref="MKDirectory"/> class from being created.
        /// </summary>
        private MKDirectory()
        {
            //Private Constructor to avoid direct initialization
        }

        /// <summary>
        /// Reads the directory.
        /// </summary>
        /// <param name="directoryPath">The directory path.</param>
        /// <returns></returns>
        public static MKDirectory Read(string directoryPath)
        {
            DirectoryInfo dir = new DirectoryInfo(directoryPath);
            return Read(directoryInfo: dir);
        }

        /// <summary>
        /// Reads the directory.
        /// </summary>
        /// <param name="directoryInfo">The directory.</param>
        /// <returns></returns>
        public static MKDirectory Read(DirectoryInfo directoryInfo)
        {
            var dir = new MKDirectory();
            dir.IsDirectory = directoryInfo.Attributes.Equals(FileAttributes.Directory);
            dir.Name = directoryInfo.Name;
            dir.ParentPath = directoryInfo.Parent.FullName;
            dir.Path = directoryInfo.FullName;

            if (dir.IsDirectory)
            {
                dir.FileCount = directoryInfo.GetFileSystemInfos().Count();
                dir.IsEmptyDirectory = directoryInfo.GetFileSystemInfos().Count() <= 0;
                dir.ChildDirectories = dir.ReadDirectories();
                dir.ChildFiles = dir.ReadFiles();
            }
            return dir;
        }

        /// <summary>
        /// Reads the directories.
        /// </summary>
        /// <returns></returns>
        private IEnumerable<MKDirectory> ReadDirectories()
        {
            DirectoryInfo currentDirectory = new DirectoryInfo(this.Path);
            return currentDirectory.EnumerateDirectories().Select(d => MKDirectory.Read(d));
        }

        /// <summary>
        /// Reads the files.
        /// </summary>
        /// <returns></returns>
        private IEnumerable<MKFile> ReadFiles()
        {
            DirectoryInfo currentDirectory = new DirectoryInfo(this.Path);
            var efiles = currentDirectory.EnumerateFiles();
            List<MKFile> files = new List<MKFile>();
            foreach (var efile in efiles)
                files.Add(MKFile.Read(efile));
            return files;
        }
    }
}
